package com.qg.cyapp.loader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;

import android.app.Activity;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

import com.qg.cyapp.util.ExecutorUtil;
import com.qg.cyapp.util.ImageUtil;
import com.qg.cyapp.util.ShareUtil;


/**
 * 图片加载工具
 * 
 * @author ZZJ
 */
public class FileLoader {

    private static final String    TAG            = "FileLoader";

    private MemoryCache            memoryCache    = new MemoryCache();
    private FileCache              fileCache      = new FileCache();
    private Map<ImageView, String> imageViews     = Collections.synchronizedMap(new WeakHashMap<ImageView, String>()); // 保存图片view及其对应的文件路径名的同步弱引用

    private int                    request_width  = 200;
    private int                    request_height = 200;
    private boolean                wrapHeight     = false;
    private String                 tag            = "FileLoader";

    public FileLoader(int request_width, int request_height, boolean wrapHeight) {
        this.request_width = request_width;
        this.request_height = request_height;
        this.wrapHeight = wrapHeight;
    }

    /**
     * 加载显示图片
     * 
     * @param url
     * @param imageView
     * @param progressBar可以不为为null时,则图片显示后隐藏
     * @param isLoadOnlyFromCache
     */
    public void displayImage(String path, ImageView imageView, ProgressBar progressBar, boolean isLoadOnlyFromCache) {
        String url = ShareUtil.IMG_BASE_URL  + path;
        imageView.setTag(url);
        imageViews.put(imageView, url);
        // 先从内存缓存中找
        Bitmap bitmap = memoryCache.get(url);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            if (progressBar != null) {
                progressBar.setVisibility(View.VISIBLE);
            }

        } else if (!isLoadOnlyFromCache) {
            // 若没有的话则开启新线程加载图片
            Log.i(TAG, "ImageLoader url= " + url);
            if (progressBar != null) {
                progressBar.setVisibility(View.VISIBLE);
            }
            queuePhoto(url, imageView, progressBar);
        }
    }

    /**
     * 开启线程加载图片
     * 
     * @param url
     * @param imageView
     */
    private void queuePhoto(String url, ImageView imageView, ProgressBar progressBar) {
        PhotoToLoad p = new PhotoToLoad(url, imageView, progressBar);
        // ExecutorUtil.getExecutorService().submit(new PhotosLoader(p));
        ExecutorUtil.getCachedExecutorService().submit(new PhotosLoader(p));
    }

    /**
     * 判断图片是否对应
     * 
     * @param photoToLoad
     * @return
     */
    private boolean imageViewReused(PhotoToLoad photoToLoad) {
        String tag = imageViews.get(photoToLoad.imageView);
        if (tag == null || !tag.equals(photoToLoad.url)) return true;
        return false;
    }

    /**
     * 从文件缓存或网上获取图片文件
     * 
     * @param url
     * @return
     */
    private Bitmap getBitmap(PhotoToLoad photoToLoad) {
        File file = fileCache.getFile(photoToLoad.url);
        // 先从文件缓存中查找是否有
        Bitmap bitmap = null;
        if (file != null && file.exists()) {
            Log.v(tag, "文件中有:"+file.toString());
            bitmap = ImageUtil.decodeFile(file, request_width, request_height, wrapHeight);
        }
        if (bitmap != null) {
            return bitmap;
        }
        // 如果没有则从指定的url中下载
        try {
            URL imageUrl = new URL(photoToLoad.url);
            HttpURLConnection connection = (HttpURLConnection) imageUrl.openConnection();
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(30000);
            connection.setInstanceFollowRedirects(true);
            if (connection.getResponseCode() != 200) return null;
            InputStream is = connection.getInputStream();
            OutputStream os = new FileOutputStream(file);
            CopyStream(is, os);
            os.close();
            connection.disconnect();
            bitmap = ImageUtil.decodeFile(file, request_width, request_height, wrapHeight);
            if (bitmap == null) {
                Log.i(TAG, "bitmap null");
            }

        } catch (Exception e) {
            Log.e(TAG, "getBitmap catch Exception...\n message = " + e.getMessage());
        }
        return bitmap;
    }

    /**
     * 将输入流写入输入流
     * 
     * @param is
     * @param os
     */
    public static void CopyStream(InputStream is, OutputStream os) {
        final int buffer_size = 1024;
        try {
            byte[] bytes = new byte[buffer_size];
            for (;;) {
                int count = is.read(bytes, 0, buffer_size);
                if (count == -1) {
                    break;
                }
                os.write(bytes, 0, count);
            }
        } catch (Exception e) {
            Log.e(TAG, "CopyStream catch Exception...");
        }
    }

    /**
     * 清空图片所占的文件和内存缓存
     */
    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }

    /**
     * 保存要显示的图片控件及其对应的图片路径的类
     */
    private class PhotoToLoad {

        public String      url;
        public ImageView   imageView;
        public ProgressBar progressBar;

        public PhotoToLoad(String url, ImageView imageView, ProgressBar progressBar) {
            this.url = url;
            this.imageView = imageView;
            this.progressBar = progressBar;
        }

    }

    /**
     * 开启新线程去文件或网上获取图片的类
     */
    class PhotosLoader implements Runnable {

        PhotoToLoad photoToLoad;

        public PhotosLoader(PhotoToLoad photoToLoad) {
            this.photoToLoad = photoToLoad;
        }

        @Override
        public void run() {
            if (imageViewReused(photoToLoad)) {
                // 如果图片已经错位，则取消
                Log.v("FileLoder 错位", "206");
                return;
            }
            Bitmap bitmap = getBitmap(photoToLoad);
            memoryCache.put(photoToLoad.url, bitmap);
            if (imageViewReused(photoToLoad)) return;

            BitmapDisplayer bd = new BitmapDisplayer(bitmap, photoToLoad);

            // // 更新的操放在UI线程中
            Activity activity = (Activity) photoToLoad.imageView.getContext();
            activity.runOnUiThread(bd);
        }

    }

    /**
     * 用于在UI线程中更新界面
     */
    class BitmapDisplayer implements Runnable {

        Bitmap      bitmap;
        PhotoToLoad photoToLoad;

        public BitmapDisplayer(Bitmap bitmap, PhotoToLoad photoToLoad) {
            this.bitmap = bitmap;
            this.photoToLoad = photoToLoad;
        }

        @Override
        public void run() {
            if (imageViewReused(photoToLoad)) return;
            if (bitmap != null) {
                photoToLoad.imageView.setImageBitmap(bitmap);
            }
            if (photoToLoad.progressBar != null) {
                photoToLoad.progressBar.setVisibility(View.GONE);
                Log.v("Bitmap Displayer ", "Progess Gone");
            }
        }
    }

}
